package cn.dapeng.base;

import java.math.BigDecimal;
import java.util.concurrent.FutureTask;

/**
 * 验证：
 * 1. 单线程和多线程的效率
 * 2. 线程数量对效率的影响
 *
 * @author spikeCong
 * @date 2022/10/14
 */
public class SingleOrMultiThread2 {

    public static final int length = 100000000;

    public static double[] data = new double[length];

    static {
        for (int i = 0; i < length; i++) {
            data[i] = Math.random();
        }
    }

    public static void m2() throws Exception {
        long begin = System.currentTimeMillis();

        FutureTask<Double> task1 = new FutureTask(() -> {
            double sum = 0;
            for (int i = 0; i < length / 2; i++) {
                sum += data[i];
            }
            return sum;
        });

        FutureTask<Double> task2 = new FutureTask(() -> {
            double sum = 0;
            for (int i = length / 2; i < length; i++) {
                sum += data[i];
            }
            return sum;
        });

        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);
        thread1.start();
        thread2.start();

        long end = System.currentTimeMillis();
        System.out.println("sum = " + print(task1.get() + task2.get()) + " \t time = " + (end - begin));
    }

    public static void m3() throws Exception {
        long begin = System.currentTimeMillis();

        int segment = Runtime.getRuntime().availableProcessors();
        FutureTask<Double>[] tasks = new FutureTask[segment];

        for (int i = 0; i < segment; i++) {
            final int index = i;

            tasks[i] = new FutureTask(() -> {
                double sum = 0;
                for (int j = (length / segment) * index; j < (length / segment) * (index + 1); j++) {
                    sum += data[j];
                }
                return sum;
            });
            Thread thread = new Thread(tasks[i]);
            thread.start();
        }

        double sum = 0;
        for (int i = 0; i < segment; i++) {
            sum += tasks[i].get();
        }
        long end = System.currentTimeMillis();
        System.out.println("sum = " + print(sum) + " \t time = " + (end - begin));
    }


    public static void main(String[] args) throws Exception {
        m2();
        m3();
    }


    public static String print(double d) {
        BigDecimal v = BigDecimal.valueOf(d);
        return v.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }
}
